#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <ctype.h>

#include "utils.h"

void errmsg(const char *fmt, ...)
{
    static char ts[21];
    va_list ap;
    time_t t = time((time_t *)NULL);
    struct tm *tt = localtime(&t);
    strftime(ts, 20, "%Y-%m-%d %H.%M.%S", tt);
    fprintf(stderr, "parse_job: info: %s: ", ts);
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    return;
}

char *string_concat(const char *s1, const char *s2)
{
    return string_concat_sep(s1, s2, (const char *)STR_SEPARATOR);
}

char *string_concat_sep(const char *s1, const char *s2, const char *sep)
{
    if (!s1 || !strlen(s1)) {
        if (!s2 || !strlen(s2)) {
            return (char *)NULL;
        } else {
            return strdup(s2);
        }
    } else {
        if (!s2 || !strlen(s2)) {
            return strdup(s1);
        } else {
            char *s = (char *) calloc(strlen(s1) + strlen(s2) + (sep? strlen(sep): 0) + 1, sizeof(char));
            strcpy(s, s1);
            if(sep) strcat(s, sep);
            strcat(s, s2);
            return s;
        }
    }
}

char *string_concat_n(int n, ...)
{
    int i;
    va_list ap;
    char *s = (char *)NULL;
    va_start(ap, n);
    for(i = 0; i < n; i++) {
        s = string_concat_sep(s, va_arg(ap, char *), (const char *)STR_SEPARATOR);
    }
    va_end(ap);
    return s;
}

char *string_concat_sep_n(int n, const char *sep, ...)
{
    int i;
    va_list ap;
    char *s = (char *)NULL;
    va_start(ap, sep);
    for(i = 0; i < n; i++) {
        s = string_concat_sep(s, va_arg(ap, char *), sep);
    }
    va_end(ap);
    return s;
}

char *escape_quote(const char *str, const char quote)
{
    register int i, c;
    int n;
    char *s;
    if (!str || !(n = strlen(str))) return (char *)"";
    for(i = c = 0; i < n; i++) if(str[i] == quote) c++;
    s = calloc(n + c + 1, sizeof(char));
    for(i = c = 0; i < n; i++, c++) {
        if(str[i] == quote) {
            s[c] = str[i];
            c++;
            s[c] = str[i];
        } else {
            s[c] = str[i];
        }
    }
    return s;
}

char *escape_sql_string(const char *str)
{
    return escape_quote(str, '\'');
}

char *escape_csv_string(const char *str)
{
    return string_concat_sep_n(3, "", "\"", escape_quote(str, '"'), "\"");
}

char *xml_encode(const char *str)
{
    /* Escaping the XML means basically replacing 5 chars with new values. These replacements are:
    **    <  --> "&lt;"
    **    >  --> "&gt;"
    **    "  --> "&quot;"
    **    '  --> "&apos;"
    **    &  --> "&amp;"
    */
    register int i, c;
    int n;
    char *s;
    if (!str || !(n = strlen(str))) return (char *)"";
    for(i = c = 0; i < n; i++) {
        switch(str[i]) {
            case '<': case '>':  c += 3; break;
            case '&':            c += 4; break;
            case '"': case '\'': c += 5; break;
        }
    }
    if(!c) return strdup(str);
    s = calloc(n + c + 1, sizeof(char));
    for(i = 0, c = -1; i < n; i++) {
        switch(str[i]) {
            case '<':
                s[++c] = '&'; s[++c] = 'l'; s[++c] = 't'; s[++c] = ';';
                break;
            case '>':
                s[++c] = '&'; s[++c] = 'g'; s[++c] = 't'; s[++c] = ';';
                break;
            case '&':
                s[++c] = '&'; s[++c] = 'a'; s[++c] = 'm'; s[++c] = 'p'; s[++c] = ';';
                break;
            case '"':
                s[++c] = '&'; s[++c] = 'q'; s[++c] = 'u'; s[++c] = 'o'; s[++c] = 't'; s[++c] = ';';
                break;
            case '\'':
                s[++c] = '&'; s[++c] = 'a'; s[++c] = 'p'; s[++c] = 'o'; s[++c] = 's'; s[++c] = ';';
                break;
            default:
                s[++c] = str[i];
        }
    }
    return s;
}

